package com.seleniti.enpareja.android.ui.view;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;

import org.ioc.commons.impl.android.common.util.ArrayAdapterAsList;
import org.ioc.commons.impl.android.common.util.ObservableChange;
import org.ioc.commons.impl.android.common.util.ObservableHashSet;
import org.ioc.commons.impl.android.common.util.OnValueChangeEventListener;
import org.ioc.commons.impl.android.common.util.SaveInstanceStateHelper;
import org.ioc.commons.impl.android.common.util.WrappedFrameLayoutAsEnum;
import org.ioc.commons.impl.android.common.util.SaveInstanceStateHelper.NullBehaviour;
import org.ioc.commons.impl.android.ui.HasEnabledWrapper;
import org.ioc.commons.impl.android.ui.HasValueWrapper;
import org.ioc.commons.ui.HasValue;
import org.ioc.commons.ui.impl.HasValueAdapter;
import org.ioc.commons.utils.Format;
import org.ioc.commons.utils.ObjectsCompat;

import android.content.Context;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
import android.support.v7.widget.ShareActionProvider;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.Checkable;
import android.widget.CheckedTextView;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.ToggleButton;

import com.seleniti.enpareja.android.R;
import com.seleniti.enpareja.android.ui.widget.PendingMark;
import com.seleniti.enpareja.android.ui.widget.WeHaveDrawable;
import com.seleniti.enpareja.controller.common.domain.LoggedUserInfo;
import com.seleniti.enpareja.controller.model.integration.database.domain.ShoppingListElement;
import com.seleniti.enpareja.controller.ui.view.ShoppingListView;
import com.seleniti.enpareja.controller.ui.view.ShoppingListView.Action;
import com.seleniti.enpareja.controller.ui.view.ShoppingListView.Event;
import com.seleniti.enpareja.controller.ui.view.ShoppingListView.Operation;
import com.seleniti.enpareja.controller.ui.view.ShoppingListView.Presenter;
import com.seleniti.enpareja.controller.ui.view.ShoppingListViewPresenter;

public class ShoppingListViewWidget extends EnParejaBaseView<Event, Operation, Action, Presenter> implements
		ShoppingListView {

	static class ShoppingListStringFormatter implements Format.StringFormatter<ShoppingListElement> {
		@Override
		public String asString(ShoppingListElement obj) {
			return obj != null ? Format.substitute("{0}{1}",
					obj.getAmount() != null && obj.getAmount() > 0 ? obj.getAmount() + " " : "", obj.getText()

			) : "";
		}
	}

	private static class ItemViewHolder {

		protected EditText amount;
		protected TextView text;
		protected boolean weHave;
	}

	private Menu mMenu;
	private boolean loading;
	private boolean enabled;
	private ActionMode actionMode;
	private ToggleButton weHaveFilter;
	private Button weHaveFilter2;
	private ArrayAdapterAsList<ShoppingListElement> aadapter;
	private ListView cellList;
	private final Set<ShoppingListElement> selection = new HashSet<ShoppingListElement>();
	private final ObservableHashSet<String> basicProductsSelection = new ObservableHashSet<String>();
	private SwipeRefreshLayout swipeLayout;
	private PendingMark weDontHaveMark;
	private FrameLayout boardPanel;
	private WrappedFrameLayoutAsEnum<Board> boardShown;
	private ArrayAdapterAsList<String> basicAadapter;
	private ListView basicProductsList;
	private Button btnAddBasics;
	private Button btnCancelBasics;
	protected boolean requiresRefresh = true;

	public ShoppingListViewWidget() {
		super(true);
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		this.setHasOptionsMenu(true);
		this.setRetainInstance(true);
	}

	@SuppressWarnings("unchecked")
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		this.presenter = new ShoppingListViewPresenter(this, eventbus, operationManager, actionController);
		
		if (savedInstanceState != null) {
			SaveInstanceStateHelper ss = new SaveInstanceStateHelper(this.getClass().getName(), savedInstanceState);

			ss.restore().value(NullBehaviour.KEEP_VALUE, this.boardShown()).value(this.loggedUserInfo()).value(this.couple());
		}

	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.shopping_list_view, container, false);

		this.boardPanel = (FrameLayout) view.findViewById(R.id.boardPanel);
		this.boardShown = null;

		this.swipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_container);
		this.swipeLayout.setOnRefreshListener(new OnRefreshListener() {

			@Override
			public void onRefresh() {
				presenter.onRefreshData();
			}
		});
		this.swipeLayout.setColorSchemeResources(android.R.color.holo_blue_bright, android.R.color.holo_green_light,
				android.R.color.holo_orange_light, android.R.color.holo_red_light);

		this.weHaveFilter = (ToggleButton) view.findViewById(R.id.weHaveFilter);
		this.weHaveFilter2 = (Button) view.findViewById(R.id.weHaveFilter2);
		this.weDontHaveMark = (PendingMark) view.findViewById(R.id.weDontHaveMark);

		this.btnAddBasics = (Button) view.findViewById(R.id.btnAddBasics);
		this.btnCancelBasics = (Button) view.findViewById(R.id.btnCancelBasics);

		this.weHaveFilter.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
				presenter.onWeHaveFilterChanged();
			}
		});

		this.weHaveFilter2.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				weHaveFilter.setChecked(!weHaveFilter.isChecked());
			}
		});

		this.btnAddBasics.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				presenter.onAddSelectedBasicElements();
			}
		});

		this.btnCancelBasics.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				presenter.onCancelAddingSelectedBasicElements();
			}
		});

		initShoppingList(view);
		initBasicProductsList(view);

		return view;
	}

	protected void initShoppingList(View view) {
		this.cellList = (ListView) view.findViewById(R.id.cellList);
		this.cellList.setEmptyView(view.findViewById(R.id.empty));
		Context context = this.getContext();
		if (this.aadapter == null || !ObjectsCompat.equals(this.aadapter.getContext(), this.getContext())) {

			List<ShoppingListElement> objects = (this.aadapter == null) ? new ArrayList<ShoppingListElement>()
					: this.aadapter;

			this.aadapter = new ArrayAdapterAsList<ShoppingListElement>(context,
					R.layout.shopping_list_we_dont_have_element, objects) {
				@Override
				public View getView(int position, View convertView, ViewGroup parent) {
					ItemViewHolder ivh = null;
					LinearLayout panel = null;
					ShoppingListElement item = this.getItem(position);

					if (convertView == null) {
						Bundle savedInstanceState = new Bundle();
						LayoutInflater inflater = getLayoutInflater(savedInstanceState);
						boolean weHave = item != null && item.isWeHave();
						ivh = new ItemViewHolder();

						if (actionMode == ActionMode.DELETE_ELEMENT) {
							convertView = inflater.inflate(android.R.layout.simple_list_item_multiple_choice, parent,
									false);

							CheckedTextView ctv = (CheckedTextView) convertView;

							ivh.text = ctv;

						} else if (weHave) {
							convertView = inflater.inflate(R.layout.shopping_list_we_have_element, parent, false);
						} else {
							convertView = inflater.inflate(R.layout.shopping_list_we_dont_have_element, parent, false);
						}

						if (convertView instanceof LinearLayout) {
							panel = (LinearLayout) convertView;

							ivh.text = (TextView) panel.findViewById(R.id.caption);
							ivh.amount = (EditText) panel.findViewById(R.id.amount);

							ivh.amount.setOnFocusChangeListener(new OnValueChangeEventListener() {

								@Override
								public void onValueChanged(View v, CharSequence s) {
									Integer amount = null;
									try {
										amount = s != null ? Integer.valueOf(s.toString()) : null;
									} catch (NumberFormatException e) {
										amount = null;
									}
									int position= (Integer) v.getTag();
									ShoppingListElement item = getItem(position);

									presenter.onAmountChanged(item, amount);
								}
							});

							// ivh.amount.addTextChangedListener(new
							// TextWatcherAdapter() {
							// public void afterTextChanged(Editable s) {
							// Integer amount = null;
							// try {
							// amount = s != null ?
							// Integer.valueOf(s.toString()) : null;
							// } catch (NumberFormatException e) {
							// amount = null;
							// }
							// presenter.onAmountChanged(item, amount);
							// };
							// });

							panel.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
									MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));

							int ps = panel.getPaddingLeft();
							int pe = panel.getPaddingRight();
							int pt = panel.getPaddingTop();
							int pb = panel.getPaddingBottom();

							int padding = Math.max(Math.max(Math.max(ps, pe), pt), pb);

							int minH = panel.getMeasuredHeight() - (padding * 2);

							WeHaveDrawable drw = new WeHaveDrawable(weHave/*
																		 * ,
																		 * null,
																		 * h,
																		 * padding
																		 */);
							drw.setMinHeight(minH);

							ivh.text.setBackground(drw);
						}
						ivh.weHave = item.isWeHave();

						convertView.setTag(ivh);
					} else {
						// panel = (LinearLayout) convertView;
						ivh = (ItemViewHolder) convertView.getTag();

						if (item != null && ivh.weHave != item.isWeHave()) {
							return getView(position, null, parent);
						}
					}

					String text = item != null ? item.getText() : "--";
					String amount = item != null && item.getAmount() != null ? item.getAmount().toString() : "";

					if (actionMode != ActionMode.SET_AMOUNT && !amount.isEmpty()) {
						text = Format.substitute("{0} {1}", amount, text);
					}
					ivh.text.setText(text);
					if (ivh.amount != null) {
						ivh.amount.setText(amount);
						ivh.amount.setVisibility(actionMode == ActionMode.SET_AMOUNT ? View.VISIBLE : View.GONE);
						ivh.amount.setTag(position);
					}

					return convertView;
				}
			};

			this.aadapter.registerDataSetObserver(new DataSetObserver() {

				@Override
				public void onChanged() {
					super.onChanged();

					if (getActivity() != null) {
						setShareIntent(new SetShareIntentParameter<ShoppingListElement>(
								getWeDontHaveElements(aadapter), new ShoppingListStringFormatter(),
								getString(R.string.shopping_list)));
					}
				}
			});
		}
		this.cellList.setAdapter(aadapter);
		this.cellList.setChoiceMode(ListView.CHOICE_MODE_NONE);
		this.cellList.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				if (actionMode != null) {
					ShoppingListElement value = (ShoppingListElement) cellList.getItemAtPosition(position);
					switch (actionMode) {
					case RENAME_ELEMENT:
						renameElement(value);
						break;
					case SWITCH_LIST:
						switchElementFromList(value);
						break;
					case DELETE_ELEMENT:
						boolean selected = !cellList.isItemChecked(position);
						cellList.setItemChecked(position, selected);

						if (selected) {
							selection.add((ShoppingListElement) cellList.getItemAtPosition(position));
						} else {
							selection.remove((ShoppingListElement) cellList.getItemAtPosition(position));
						}

						presenter.onSelectionChanged();
						break;
					default:
						/*
						 * Nothing to do
						 */
					}
				}
			}
		});

		/*
		 * Required for multi choice even when there are no actions
		 */
		// Capture ListView item click
		this.cellList.setMultiChoiceModeListener(new MultiChoiceModeListener() {

			@Override
			public boolean onCreateActionMode(android.view.ActionMode mode, Menu menu) {
				return false;
			}

			@Override
			public boolean onPrepareActionMode(android.view.ActionMode mode, Menu menu) {
				return false;
			}

			@Override
			public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item) {
				return false;
			}

			@Override
			public void onDestroyActionMode(android.view.ActionMode mode) {

			}

			@Override
			public void onItemCheckedStateChanged(android.view.ActionMode mode, int position, long id, boolean checked) {
				// TODO Auto-generated method stub

			}

		});
	}

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		super.onCreateOptionsMenu(menu, inflater);

		inflater.inflate(R.menu.shopping_list_menu, menu);

		this.mMenu = menu;

		// MenuItem btnAdd = mMenu.findItem(R.id.add_item);
		MenuItem btnModify = mMenu.findItem(R.id.modify_item);
		MenuItem btnSetAmount = mMenu.findItem(R.id.set_amount_item);
		MenuItem btnDelete = mMenu.findItem(R.id.delete_item);
		// Locate MenuItem with ShareActionProvider
		MenuItem btnShare = menu.findItem(R.id.menu_item_share);

		// Fetch and store ShareActionProvider
		this.mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(btnShare);
		setShareIntent(new SetShareIntentParameter<ShoppingListElement>(getWeDontHaveElements(aadapter),
				new ShoppingListStringFormatter(), getString(R.string.shopping_list) + " ("
						+ getString(R.string.we_dont_have) + ")"));
		btnShare.setVisible(this.mShareActionProvider != null);

		btnModify.setChecked(this.actionMode == ActionMode.RENAME_ELEMENT);
		btnModify.setIcon(btnModify.isChecked() ? R.drawable.modify_icon_on : R.drawable.modify_icon);

		btnDelete.setChecked(this.actionMode == ActionMode.DELETE_ELEMENT);
		btnDelete.setIcon(btnDelete.isChecked() ? R.drawable.bin_icon_on : R.drawable.bin_icon);

		btnSetAmount.setChecked(this.actionMode == ActionMode.SET_AMOUNT);
		btnSetAmount.setIcon(btnSetAmount.isChecked() ? R.drawable.balance_icon_on : R.drawable.balance_icon);

	}

	private List<ShoppingListElement> getWeDontHaveElements(List<ShoppingListElement> list) {
		List<ShoppingListElement> result = null;
		if (list != null) {
			result = new ArrayList<ShoppingListElement>(list.size());

			for (ShoppingListElement e : list) {
				if (!e.isWeHave()) {
					result.add(e);
				}
			}
		}
		return result;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.add_item:
			this.setActionMode(ActionMode.SWITCH_LIST);
			this.addNewElement();
			return true;
		case R.id.modify_item:
			presenter.onModifyButtonToggled(this.getActionMode() != ActionMode.RENAME_ELEMENT);
			return true;
		case R.id.delete_item:
			this.setActionMode(this.getActionMode() != ActionMode.DELETE_ELEMENT ? ActionMode.DELETE_ELEMENT
					: ActionMode.SWITCH_LIST);
			return true;
		case R.id.set_amount_item:
			this.setActionMode(this.getActionMode() != ActionMode.SET_AMOUNT ? ActionMode.SET_AMOUNT
					: ActionMode.SWITCH_LIST);
			return true;
		case R.id.basic_products_item:
			this.showBasics();
			return true;
		default:
			this.setActionMode(ActionMode.SWITCH_LIST);
			return super.onOptionsItemSelected(item);
		}
	}

	@Override
	public void setLoading(boolean loading) {
		this.loading = loading;
		if (mMenu != null) {
			MenuItem btnAdd = mMenu.findItem(R.id.add_item);
			MenuItem btnModify = mMenu.findItem(R.id.modify_item);
			MenuItem btnDelete = mMenu.findItem(R.id.delete_item);
			MenuItem btnSetAmount = mMenu.findItem(R.id.set_amount_item);

			btnAdd.setEnabled(!loading);
			btnModify.setEnabled(!loading);
			btnDelete.setEnabled(!loading);
			btnSetAmount.setEnabled(!loading);
		}

		if (this.swipeLayout != null) {
			this.swipeLayout.setRefreshing(loading);
		}
	}

	@Override
	public boolean isLoading() {
		return this.loading;
	}

	@Override
	public boolean isEnabled() {
		return this.enabled;
	}

	@Override
	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
		if (mMenu != null) {
			MenuItem btnAdd = mMenu.findItem(R.id.add_item);
			MenuItem btnModify = mMenu.findItem(R.id.modify_item);
			MenuItem btnSetAmount = mMenu.findItem(R.id.set_amount_item);
			MenuItem btnDelete = mMenu.findItem(R.id.delete_item);

			HasEnabledWrapper.setEnabled(enabled, btnAdd, btnDelete, btnModify, btnSetAmount);
		}
	}

	@Override
	public void setActionMode(ActionMode mode) {
		boolean changed = !ObjectsCompat.equals(this.actionMode, mode);
		ActionMode newMode = mode;
		boolean requiresRepaint = checkRequiresRepaint(newMode, ActionMode.DELETE_ELEMENT);
		requiresRepaint |= checkRequiresRepaint(newMode, ActionMode.SET_AMOUNT);
		this.actionMode = mode;

		if (mode != null) {
			switch (mode) {
			case SWITCH_LIST:
				this.cellList.setChoiceMode(ListView.CHOICE_MODE_NONE);
				break;
			case DELETE_ELEMENT:
				this.cellList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
				break;
			case RENAME_ELEMENT:
				this.cellList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
				break;
			case SET_AMOUNT:
				this.cellList.setChoiceMode(ListView.CHOICE_MODE_NONE);
				break;
			}
		}

		if (this.getActivity() != null) {
			this.getActivity().invalidateOptionsMenu();
		}

		if (requiresRepaint && this.cellList != null) {

			this.saveScrollPosition(cellList);

			/*
			 * Clear all recycled views, so they will be repainted properly
			 */
			this.cellList.setAdapter(aadapter);

			this.restoreScrollPosition(cellList);
		}

		if (changed) {
			this.presenter.onActionModeChanged();
		}

	}

	private boolean checkRequiresRepaint(ActionMode newMode, ActionMode differentFromThis) {
		boolean requiresRepaint = (newMode == differentFromThis && actionMode != differentFromThis)
				|| (newMode != differentFromThis && actionMode == differentFromThis);
		return requiresRepaint;
	}

	@Override
	public ActionMode getActionMode() {
		return this.actionMode;
	}

	@Override
	public void addNewElement() {
		this.presenter.onAddNewElement();
	}

	@Override
	public void renameElement(ShoppingListElement element) {
		this.presenter.onRenameElement(element);
	}

	@Override
	public HasValue<Boolean> weDontHaveFilter() {
		return HasValueWrapper.from((Checkable) weHaveFilter, this);
	}

	@Override
	public List<ShoppingListElement> shoppingList() {
		return this.aadapter;
	}

	@Override
	public Set<ShoppingListElement> getSelection() {
		return this.selection;
	}

	@Override
	public void switchElementFromList(ShoppingListElement value) {
		presenter.onSwitchElementFromList(value);
	}

	@Override
	public HasValue<Integer> weDontHaveCounter() {
		return this.weDontHaveMark;
	}

	@Override
	public void scrollToElement(int idx) {
		cellList.smoothScrollToPosition(idx);
	}

	@Override
	public void showBasics() {
		presenter.onShowBasics();
	}

	@Override
	public HasValue<Board> boardShown() {
		if (this.boardShown == null) {
			this.boardShown = new WrappedFrameLayoutAsEnum<ShoppingListView.Board>(this.boardPanel,
					ShoppingListView.Board.values());
			// TODO: Slide effect
		}

		return this.boardShown;
		// return HasValueAdapter.<HomeTasksView.Board> forField("boardShown",
		// this).onChange(
		// new OnChangeCommand<HomeTasksView.Board>() {
		//
		// @Override
		// public void execute(Board value) {
		// if (value == null) {
		// value = Board.TASKS_LIST;
		// }
		//
		// switch (value) {
		// case FORM:
		// list.setVisibility(View.GONE);
		// basicTasksPanel.setVisibility(visibility);
		// form.setVisibility(View.VISIBLE);
		// break;
		// case TASKS_LIST:
		// list.setVisibility(View.VISIBLE);
		// form.setVisibility(View.GONE);
		// // TODO: Slide effect
		// break;
		// default:
		// throw new IllegalArgumentException("Unknown board: " + value);
		// }
		//
		// }
		// });
	}

	protected void initBasicProductsList(View view) {
		this.basicProductsList = (ListView) view.findViewById(R.id.basicProductsList);

		Context context = this.getContext();
		if (this.basicAadapter == null || !ObjectsCompat.equals(this.basicAadapter.getContext(), this.getContext())) {

			List<String> objects = (this.basicAadapter == null) ? new ArrayList<String>() : this.basicAadapter;

			this.basicAadapter = new ArrayAdapterAsList<String>(context,
					android.R.layout.simple_list_item_multiple_choice, objects) {
				@Override
				public View getView(int position, View convertView, ViewGroup parent) {
					ItemViewHolder ivh = null;
					final String text = this.getItem(position);

					if (convertView == null) {
						Bundle savedInstanceState = new Bundle();
						LayoutInflater inflater = getLayoutInflater(savedInstanceState);
						ivh = new ItemViewHolder();

						convertView = inflater
								.inflate(android.R.layout.simple_list_item_multiple_choice, parent, false);

						CheckedTextView ctv = (CheckedTextView) convertView;

						ivh.text = ctv;

						convertView.setTag(ivh);
					} else {
						// panel = (LinearLayout) convertView;
						ivh = (ItemViewHolder) convertView.getTag();
					}

					ivh.text.setText(text);

					return convertView;
				}
			};
		}

		this.basicProductsList.setAdapter(this.basicAadapter);
		this.basicProductsList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
		this.basicProductsList.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				boolean selected = basicProductsList.isItemChecked(position);
				// basicProductsList.setItemChecked(position, selected);

				boolean previous = ShoppingListViewWidget.this.requiresRefresh;
				ShoppingListViewWidget.this.requiresRefresh = false;
				if (selected) {
					basicProductsSelection.add((String) basicProductsList.getItemAtPosition(position));
				} else {
					basicProductsSelection.remove((String) basicProductsList.getItemAtPosition(position));
				}
				ShoppingListViewWidget.this.requiresRefresh = previous;
			}
		});
		this.basicProductsSelection.addObserver(new Observer() {

			@Override
			public void update(Observable observable, final Object data) {
				if (ShoppingListViewWidget.this.requiresRefresh) {
					ShoppingListViewWidget.this.requiresRefresh = false;
					new Handler().post(new Runnable() {

						@Override
						public void run() {
							ObservableChange oc = (ObservableChange) data;
							@SuppressWarnings("unchecked")
							Collection<String> elements = (Collection<String>) oc.getElements();

							for (String element : elements) {
								int idx = basicAadapter.indexOf(element);
								if (idx >= 0) {
									switch (oc.getOperation()) {
									case Add:
										basicProductsList.setItemChecked(idx, true);
//										child.setChecked(true);
										break;
									case Remove:
										basicProductsList.setItemChecked(idx, false);
//										child.setChecked(false);
										break;
									default:
										/*
										 * Nothing to do
										 */
									}
								}
							}
							ShoppingListViewWidget.this.requiresRefresh = true;
						}
					});
				}

			}
		});

		// Capture ListView item click
		this.basicProductsList.setMultiChoiceModeListener(new MultiChoiceModeListener() {

			@Override
			public boolean onCreateActionMode(android.view.ActionMode mode, Menu menu) {
				return false;
			}

			@Override
			public boolean onPrepareActionMode(android.view.ActionMode mode, Menu menu) {
				return false;
			}

			@Override
			public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item) {
				return false;
			}

			@Override
			public void onDestroyActionMode(android.view.ActionMode mode) {

			}

			@Override
			public void onItemCheckedStateChanged(android.view.ActionMode mode, int position, long id, boolean checked) {

			}

		});
	}

	@Override
	public List<String> basicProducts() {
		return this.basicAadapter;
	}

	@Override
	public Set<String> selectedBasicProducts() {
		return this.basicProductsSelection;
	}

	@Override
	public boolean goBoardBack() {
		return presenter.onGoBoardBack();
	}
	
	
	@SuppressWarnings("unchecked")
	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);

		SaveInstanceStateHelper ss = new SaveInstanceStateHelper(this.getClass().getName(), outState);

		ss.save().value(this.boardShown()).value(this.loggedUserInfo()).value(this.couple());
	}

	@Override
	public HasValue<LoggedUserInfo> loggedUserInfo() {
		return HasValueAdapter.<LoggedUserInfo>forField("loggedUserInfo", this);
	}
}
